package com.baidu.iit.pxp.behavior;

import com.baidu.iit.pvm.ActivityException;
import com.baidu.iit.pvm.PvmTransition;
import com.baidu.iit.pvm.delegate.ActivityExecution;
import com.baidu.iit.pvm.delegate.Condition;
import com.baidu.iit.pxp.handler.GatewayActivityBehavior;
import com.baidu.iit.pxp.parser.BpmnParse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Iterator;

/**
 * User: huangweili
 * Date: 14-4-27
 * Time: 上午9:18
 */
public class ExclusiveGatewayActivityBehavior extends GatewayActivityBehavior {

    private static Logger logger = LoggerFactory.getLogger(ExclusiveGatewayActivityBehavior.class);

    @Override
    protected void leave(ActivityExecution execution) {

        if (logger.isDebugEnabled()) {
            logger.debug("Leaving activity '{}'", execution.getActivity().getId());
        }

        PvmTransition outgoingSeqFlow = null;
        String defaultSequenceFlow = (String) execution.getActivity().getProperty("default");
        Iterator<PvmTransition> transitionIterator = execution.getActivity().getOutgoingTransitions().iterator();
        while (outgoingSeqFlow == null && transitionIterator.hasNext()) {
            PvmTransition seqFlow = transitionIterator.next();

            Condition condition = (Condition) seqFlow.getProperty(BpmnParse.PROPERTYNAME_CONDITION);
            if ((condition == null && (defaultSequenceFlow == null || !defaultSequenceFlow.equals(seqFlow.getId())))
                    || (condition != null && condition.evaluate(execution))) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Sequence flow '{}'selected as outgoing sequence flow.", seqFlow.getId());
                }
                outgoingSeqFlow = seqFlow;
            }
        }

        if (outgoingSeqFlow != null) {
            execution.take(outgoingSeqFlow);
        } else {

            if (defaultSequenceFlow != null) {
                PvmTransition defaultTransition = execution.getActivity().findOutgoingTransition(defaultSequenceFlow);
                if (defaultTransition != null) {
                    execution.take(defaultTransition);
                } else {
                    throw new ActivityException("Default sequence flow '" + defaultSequenceFlow + "' not found");
                }
            } else {
                throw new ActivityException("No outgoing sequence flow of the exclusive gateway '"
                        + execution.getActivity().getId() + "' could be selected for continuing the process");
            }
        }
    }

}
